<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
        <title></title>
        <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
	</head>
	<body>
		<p>render  函数</p>
		render 函数是什么
		简单的说是在vue中，我们使用模板html 语法组件页面，使用render 函数我们可以用js 语言构建dom
		因为vue是虚拟dom 所以在拿到template 模板也要转义成VNode 的函数，而用render 函数构建Dom 可以免去
		转义的过程，　当使用render函数描述虚拟DOM时，vue提供一个函数，这个函数是就构建虚拟DOM所需要的工具。
		官网上给他起了个名字叫createElement。
		类似于，正常我们使用html 模板，但是我们可以用js 添加模板内容，，render 就是在vue中实现js 的

		render函数怎么用


		示例
		<code>
			render:(h) => {
				return h('div',{
			　　　//给div绑定value属性
					 props: {
							 value:''
					 },
			　　　//给div绑定样式
			　　　style:{
			　　　　　width:'30px'
			　　　},　
			　　　//给div绑定点击事件　　
					 on: {
							 click: () => {
									console.log('点击事件')
							 }
					 },
				})
			}

		</code>
		比如上面的就会在页面上加上<div>xxxx</div>包含了，样式，和点击事件

		总结： 
1. render方法的实质就是生成template模板； 
2. 通过调用一个方法来生成，而这个方法是通过render方法的参数传递给它的； 
3. 这个方法有三个参数，分别提供标签名，标签相关属性，标签内部的html内容 
4. 通过这三个参数，可以生成一个完整的木模板

备注：

render方法可以使用JSX语法，但需要Babel plugin插件；
render方法里的第三个参数可以使用函数来生成多个组件（特别是如果他们相同的话），只要生成结果是一个数组，且数组元素都是VNode即可；
注意： 


render  的函数
---------------------------------------------------------------------------------------------------------------
/**
* render: 渲染函数
* 参数: createElement
* 参数类型: Function
*/
render: function (createElement) {
 let _this = this['$options'].parent	// 我这个是在 .vue 文件的 components 中写的，这样写才能访问this
 let _header = _this.$slots.header   	// $slots: vue中所有分发插槽，不具名的都在default里

 /**
	* createElement 本身也是一个函数，它有三个参数
	* 返回值: VNode，即虚拟节点
	* 1. 一个 HTML 标签字符串，组件选项对象，或者解析上述任何一种的一个 async 异步函数。必需参数。{String | Object | Function} - 就是你要渲染的最外层标签
	* 2. 一个包含模板相关属性的数据对象你可以在 template 中使用这些特性。可选参数。{Object} - 1中的标签的属性
	* 3. 子虚拟节点 (VNodes)，由 `createElement()` 构建而成，也可以使用字符串来生成“文本虚拟节点”。可选参数。{String | Array} - 1的子节点，可以用 createElement() 创建，文本节点直接写就可以
	*/
 return createElement(       
	 // 1. 要渲染的标签名称：第一个参数【必需】      
	 'div',   
	 // 2. 1中渲染的标签的属性，详情查看文档：第二个参数【可选】
	 {
		 style: {
			 color: '#333',
			 border: '1px solid #ccc'
		 }
	 },
	 // 3. 1中渲染的标签的子元素数组：第三个参数【可选】
	 [
		 'text',   // 文本节点直接写就可以
		 _this.$slots.default,  // 所有不具名插槽，是个数组
		 createElement('div', _header)   // createElement()创建的VNodes
	 ]
 )
}
---------------------------------------------------------------------------------------------------------------

非render 用法
<code> 
	<div id="app">
    <child :level="1">Hello world!</child>
</div>
<script type="text/x-template" id="template">
<div>
    <h1 v-if="level === 1">
        <slot></slot>
    </h1>
 
    <h2 v-if="level === 2">
        <slot></slot>
    </h2>
 
    <h3 v-if="level === 3">
        <slot></slot>
    </h3>
 
    <h4 v-if="level === 4">
        <slot></slot>
    </h4>
 
    <h5 v-if="level === 5">
        <slot></slot>
    </h5>
 
    <h6 v-if="level === 6">
        <slot></slot>
    </h6>
</div>
</script>
 
 
 
<script type="text/javascript">
 
Vue.component('child', {
    template: '#template',
    props: {
        level: {
            type: Number,
            required: true
        }
    }
})
 
new Vue({
    el: "#app"
})
 
</script>

</code>    <code>


	<div id="app">
    <child v-bind:level="2">Hello world!</child>
</div>
 
<script type="text/javascript">
 
Vue.component('child', {
    render: function (createElement) {
        return createElement(
            'h' + this.level, // tag name 标签名称
            this.$slots.default // 子组件中的阵列
        )
    },
    props: {
        level: {
            type: Number,
            required: true
        }
    }
})
 
new Vue({
    el: "#app"
})
 
</script>
</code>

理解：在组件封装的时候，使用render render 的第二个第三个参数是可选的，可以使用第一个，第三个参数，
	
	</body>
</html>
